package com.ruoyi.web.controller.api.city;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.model.CityLoginUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.utils.file.MimeTypeUtils;
import com.ruoyi.framework.web.service.TokenService;
import com.ruoyi.system.domain.city.CityCollect;
import com.ruoyi.system.domain.city.CityProject;
import com.ruoyi.system.domain.city.CityUser;
import com.ruoyi.system.service.city.ICityCollectService;
import com.ruoyi.system.service.city.ICityProjectService;
import com.ruoyi.system.service.city.ICityUserService;
import com.ruoyi.web.core.utils.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

import static com.ruoyi.common.utils.file.FileUploadUtils.assertAllowed;

/**
 * 登录Controller
 *
 * @author cjq
 * @date 2023-07-25
 */
@RestController
@RequestMapping("/api/city/login")
public class CityLoginController extends BaseController {


    @Autowired
    private TokenService tokenService;

    @Autowired
    private ICityUserService  iCityUserService;

    @Autowired
    StringRedisTemplate redisTemplate;

    @Autowired
    private ICityUserService cityUserService;





    @Value("${weixin.appid}")
    private String appid;

    @Value("${weixin.secret}")
    private String secret;

    public static final String WX_SESSION_ID = "wx_session_id";



    /**
     * 获取微信号详细信息
     */
    @GetMapping(value = "/getUser")
    public CityUser getInfo(@RequestParam("userId") String openid)
    {
        CityUser cityUser=new CityUser();
        cityUser.setOpenid(openid); //可能是用户唯一标识 也可能是手机号
        cityUser.setUserType(0);
        List<CityUser>  cityUsers=cityUserService.selectCityUserList(cityUser);
        return cityUsers.get(0);
    }


    /**
     * 修改微信号
     */

    @PostMapping(value ="/updateUser")
    public AjaxResult edit(@RequestBody CityUser cityUser)
    {

        return toAjax(cityUserService.updateCityUser(cityUser));
    }

    /**
     * 头像上传
     */

    @PostMapping("/avatar")
    public AjaxResult avatar(@RequestParam("avatarfile") MultipartFile file,@RequestParam("userId") Long  userId) throws Exception {
        String avatar="";
        if (!file.isEmpty()) {
            //效验文件大小
            assertAllowed(file, MimeTypeUtils.IMAGE_EXTENSION);
            avatar = OSSUtil.uploadFile2(file);
            //   String avatar=OSSUtil.uploadFile(file);
            System.out.println(avatar);
            CityUser cityUser=new CityUser();
            cityUser.setUserId(userId);
            cityUser.setAvatar(avatar);
            cityUserService.updateCityUser(cityUser);
        }
        return success(avatar);
    }

    //小程序登录获取的getSessuionId
    @GetMapping("/getSessionId")
    public Map<String, Object> getSessionId(@RequestParam("code") String code) {
        System.out.println(code);
        Map<String, Object> map = new HashMap<>();

        String result = HttpUtil.get(" https://api.weixin.qq.com/sns/jscode2session?appid="
                + appid + "&secret=" + secret + "&js_code=" + code + "&grant_type=authorization_code");
        System.out.println(result);
        if (JSONUtil.parseObj(result).get("openid") != null) {
            map.put("openid", JSONUtil.parseObj(result).getStr("openid"));
        }
        if (JSONUtil.parseObj(result).get("session_key")!=null){
            map.put("session_key", JSONUtil.parseObj(result).getStr("session_key"));
        }
        if (JSONUtil.parseObj(result).get("unionid") != null) {
            map.put("unionid", JSONUtil.parseObj(result).getStr("unionid"));
        }
        if (JSONUtil.parseObj(result).get("errcode") != null) {
            map.put("errcode", JSONUtil.parseObj(result).getStr("errcode"));
        }
        if (JSONUtil.parseObj(result).get("errmsg") != null) {
            map.put("errmsg", JSONUtil.parseObj(result).getStr("errmsg"));
        }
        System.out.println(result);
        String s = UUID.randomUUID().toString();
        redisTemplate.opsForValue().set(WX_SESSION_ID + s, result);
        map.put("sessionId", s);
        return map;

    }


    //小程序手机号登录
    @GetMapping("/phoneNumberLogin")
    public Map<String, Object> phoneNumberLogin(@RequestParam("code") String code,@RequestParam("phoneNumber") String phoneNumber) throws ParseException {
        System.out.println(code);
        Map<String, Object> map = new HashMap<>();
        String result = HttpUtil.get(" https://api.weixin.qq.com/sns/jscode2session?appid="
                + appid + "&secret=" + secret + "&js_code=" + code + "&grant_type=authorization_code");
        System.out.println(result);
        CityLoginUser cityLoginUser=new CityLoginUser();
        CityUser cityUser = new CityUser();
        if (JSONUtil.parseObj(result).get("openid") != null) {
            cityUser.setOpenid(JSONUtil.parseObj(result).getStr("openid"));
        }
        Long  userId= IdUtil.getSnowflakeNextId();
        System.out.println("userId"+userId);
        cityUser.setUserId(userId);
        cityUser.setStatus(0);
        cityUser.setNickName(phoneNumber);
        cityUser.setPhonenumber(phoneNumber);
        cityUser.setCity("");
        cityUser.setAvatar("city/2023/08/15/a4038249117f8b198f9698874e28def_20230815121626A002.png");
        cityUser.setCountry("中国");
        cityUser.setLanguage("zh_CN");
        cityUser.setLoginIp(cityLoginUser.getIpaddr());
        cityUser.setLoginLocation(cityLoginUser.getLoginLocation());
        //long转Date
        SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(sd.format(new Date()));
        cityUser.setLoginDate(date);
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("phonenumber", cityUser.getPhonenumber());
        CityUser cityUserDB = iCityUserService.getOne(queryWrapper);
        if (cityUserDB != null) {
            if (!cityUser.getOpenid().equals(cityUserDB.getOpenid())){
                return  error();
            }
            cityUser.setUserId(cityUserDB.getUserId());
            cityUser.setAvatar(cityUserDB.getAvatar());
            cityUserDB.setLoginIp(cityLoginUser.getIpaddr());
            cityUserDB.setLoginLocation(cityLoginUser.getLoginLocation());
            iCityUserService.updateCityUser(cityUserDB);
        } else {
            queryWrapper.eq("openid", cityUser.getOpenid());
            CityUser cityUserdb= iCityUserService.getOne(queryWrapper);
            if (cityUserdb!=null){
                return  error();
            }
            cityUser.setCreateTime(new Date());
            iCityUserService.insertCityUser(cityUser);
        }
        cityLoginUser.setUserId(cityUser.getUserId());
        String token = tokenService.createToken(cityLoginUser);
        cityUser.setToken(token);
        map.put("state", true);
        map.put("token", token);
        map.put("userId",cityUser.getUserId().toString());
        map.put("avatar",cityUser.getAvatar());
        map.put("name",cityUser.getNickName());
        return map;
    }




    //获取手机号
    @GetMapping("/getPhoneNumber")
    public String getCode(@RequestParam("code") String code) throws ParseException {
        System.out.println(code);
        Map<String, Object> map = new HashMap<>();
        //先获取access_token = appid + secret
        String result2 = HttpUtil.get("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appid + "&secret=" + secret);
        String accessToken="";
        if(JSONUtil.parseObj(result2).get("access_token") != null){
            accessToken =JSONUtil.parseObj(result2).get("access_token").toString();
        }
        System.out.println("access_token:"+accessToken);
        //用 access_token + code 获取手机号
        JSONObject jsonCode = new JSONObject();
        jsonCode.put("code",code);
        String resPhone = HttpUtil.post("https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=" + accessToken, jsonCode.toString());
        String phoneNumber="";
        if(!StringUtils.isEmpty(resPhone) || resPhone.contains("phone_info") || resPhone.contains("phoneNumber")){
            JSONObject resPhoneInfo = JSON.parseObject(resPhone);
            JSONObject phoneInfo=resPhoneInfo.getJSONObject("phone_info");
            phoneNumber = phoneInfo.get("phoneNumber").toString();
        }
        return phoneNumber;
    }



    //微信登录
    @PostMapping("/wxlogin")
    public Map<String, Object> wxlogin(@RequestBody WxAuth wxAuth) {
        Map<String, Object> map = new HashMap<>();
        try {
            if (StrUtil.isBlank(wxAuth.getOpenid())){
                map.put("state", false);
                return map;
            }
            String wxRes = wxDecrypt(wxAuth.getEncryptedData(), wxAuth.getSessionId(), wxAuth.getIv());
            System.out.println("用户信息：" + wxRes);

            if (wxRes==null){
                map.put("state", false);
            }else{
                //用户信息：{"openId":"o20","nickName":"juana","gender":2,"language":"zh_CN","city":"Changsha","province":"Hunan","country":"China","avatarUrl":"头像链接","watermark":{"timestamp":dsfs,"appid":"应用id"}}
                WxUserInfo wxUserInfo = JSON.parseObject(wxRes, WxUserInfo.class);
                // 业务操作：你可以在这里利用数据 对数据库进行查询， 如果数据库中没有这个数据，就添加进去，即实现微信账号注册
                // 如果是已经注册过的，就利用数据，生成jwt 返回token，实现登录状态
//            ShopLoginUser shopLoginUser=new ShopLoginUser();
                CityLoginUser cityLoginUser=new CityLoginUser();
                CityUser cityUser = new CityUser();
                cityUser.setOpenid(wxAuth.getOpenid());
                cityUser.setUserId(IdUtil.getSnowflakeNextId());
                cityUser.setUserName(wxUserInfo.getNickName());
                cityUser.setNickName(wxUserInfo.getNickName());
                //    userService.registerUser(sysUser);
                String token = tokenService.createToken(cityLoginUser);
                //获取令牌
                // String token = tokenService.createToken(shopLoginUser);

                cityUser.setUserId(IdUtil.getSnowflakeNextId());
                cityUser.setToken(token);
                cityUser.setStatus(1);
                cityUser.setAvatar(wxUserInfo.getAvatarUrl());
                cityUser.setCity(wxUserInfo.getCity());
                cityUser.setCountry(wxUserInfo.getCountry());
                cityUser.setLanguage(wxUserInfo.getLanguage());
                cityUser.setProvince(wxUserInfo.getProvince());
                cityUser.setNickName(wxUserInfo.getNickName());
                cityUser.setLoginIp(cityLoginUser.getIpaddr());
                cityUser.setLoginLocation(cityLoginUser.getLoginLocation());
                //long转Date
                SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                Date date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(sd.format(new Date(cityLoginUser.getLoginTime())));
                cityUser.setLoginDate(date);
                QueryWrapper queryWrapper = new QueryWrapper();
                queryWrapper.eq("openid", cityUser.getOpenid());
                CityUser cityUserDB = iCityUserService.getOne(queryWrapper);
                if (cityUserDB != null) {
                    cityUser.setUserId(cityUserDB.getUserId());
                    BeanUtil.copyProperties(cityUser, cityUserDB);
                    iCityUserService.updateCityUser(cityUserDB);
                } else {
                    cityUser.setCreateTime(new Date());
                    iCityUserService.insertCityUser(cityUser);
                }
                map.put("state", true);
                map.put("token", token);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return map;
    }

    private String wxDecrypt(String encryptedData, String sessionId, String vi) {
        try {
            //开始解密
            String json = redisTemplate.opsForValue().get(WX_SESSION_ID + sessionId);
            System.out.println("之前存储在redis中的信息：" + json);
            System.out.println("encryptedData：" + encryptedData);
            System.out.println("vi：" + vi);
            //之前存储在redis中的信息：{"session_key":"G59Evf\/Em54X6WsFsrpA1g==","openid":"o2ttv5L2yufc4-VoSPhTyUnToY60"}
            JSONObject jsonObject = JSON.parseObject(json);
            String sessionKey = (String) jsonObject.get("session_key");
            return WeChatUtil.wxDecrypt(encryptedData,sessionKey,vi);
        }catch (Exception e){
            return null;
        }

    }



}
